#!/bin/bash

#相同目录文件增量更新脚本-任意地方执行脚本,目录需要绝对路径
#功能：比较源目录和目标目录的差异，先备份目标目录中要被更新的文件，再执行覆盖更新
#用法：./incremental-update.sh <源目录> <目标目录> [备份目录-可选(默认"./update_backups/时间/....")]  eg:./incremental-update.sh ./v2.1 ./current ./my_backups/
#  使用绝对路径：bash -x /c/Users/whkj/Desktop/up_back/incremental-update.sh /e/company-project/wh-mall-saber/back_dir /e/company-project/wh-mall-saber /e/company-project/wh-mall-saber/update_backups
#失败还原cp -a 备份目录/* 目标目录/

#检查参数
if [ $# -lt 2 ]; then
    echo "用法: $0 <源目录> <目标目录> [备份目录]"
    echo "示例: $0 ./new-version ./current-version ./backups"
    exit 1
fi

#规范化目录路径（确保以/结尾）
SRC_DIR=$(realpath "$1")/
DST_DIR=$(realpath "$2")/
# 默认备份目录带时间戳
BACKUP_DIR=${3:-./update_backups/$(date +%Y%m%d_%H%M%S)}  

#检查源目录和目标目录是否存在
if [ ! -d "$SRC_DIR" ]; then
    echo  "错误：源目录 $SRC_DIR 不存在！"
    exit 1
fi

if [ ! -d "$DST_DIR" ]; then
    echo "错误：目标目录 $DST_DIR 不存在！"
    exit 1
fi

#创建备份目录
mkdir -p "$BACKUP_DIR"
echo "备份目录: $BACKUP_DIR"

#获取差异文件列表（仅源目录中存在或有变化的文件）
#排除目录，只处理文件
DIFF_FILES=$(diff -qr "$SRC_DIR" "$DST_DIR" | grep -v "Only in" | awk '{print $2}' | sed "s|$SRC_DIR||")

if [ -z "$DIFF_FILES" ]; then
    echo "源目录和目标目录没有差异文件，无需更新"
    exit 0
fi

#第一步：备份目标目录中将要被更新的文件
echo -e "\n===== 开始备份差异文件 ====="
while IFS= read -r FILE; do
    # 跳过空行
    [ -z "$FILE" ] && continue
    
    SRC_FILE="$SRC_DIR$FILE"
    DST_FILE="$DST_DIR$FILE"
    BACKUP_FILE="$BACKUP_DIR/$FILE"
    
    # 只备份目标目录中已存在的文件（新增文件无需备份）
    if [ -f "$DST_FILE" ]; then
        # 创建备份文件的目录结构
        mkdir -p "$(dirname "$BACKUP_FILE")"
        
        # 执行备份
        cp -a "$DST_FILE" "$BACKUP_FILE"
        echo "已备份: $FILE"
    fi
done <<< "$DIFF_FILES"

#第二步：执行增量更新（覆盖目标目录文件）
echo -e "\n===== 开始执行增量更新 ====="
while IFS= read -r FILE; do
    # 跳过空行
    [ -z "$FILE" ] && continue
    
    SRC_FILE="$SRC_DIR$FILE"
    DST_FILE="$DST_DIR$FILE"
    
    # 创建目标文件的目录结构（如果需要）
    mkdir  -p "$(dirname "$DST_FILE")"
    
    # 执行覆盖更新
    cp -a "$SRC_FILE" "$DST_FILE"
    echo "已更新: $FILE"
done <<< "$DIFF_FILES"

echo -e "\n===== 操作完成 ====="
echo "更新总结：共处理 $(echo "$DIFF_FILES" | wc -l) 个差异文件"
echo "备份文件位置：$BACKUP_DIR"
echo "如果需要回滚，请执行：cp -a $BACKUP_DIR/* $DST_DIR"
